﻿using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace Puzzle {
    // 图片控件
    public partial class PictureCtrl: UserControl {
        // 矩形
        private struct RECT {
            public int l;   // 左边界坐标
            public int t;   // 上边界坐标
            public int r;   // 右边界坐标
            public int b;   // 下边界坐标
            
            /**
             * 构造方法。
             * @param left      左边界坐标
             * @param top       上边界坐标
             * @param right     右边界坐标
             * @param bottom    下边界坐标
             */
            public RECT(int left, int top, int right, int bottom) {
                l = left;
                t = top;
                r = right;
                b = bottom;
            }

            /**
             * 构造方法。
             * @param rect  矩形
             */
            public RECT(Rectangle rect) {
                l = rect.Left;
                t = rect.Top;
                r = rect.Right;
                b = rect.Bottom;
            }
        }

        // 回调
        public interface Callback {
            void MovePicture(PictureCtrl picCtrl);  // 图片控件的单击事件
        }

        // 导入画矩形边框的 API 函数
        [DllImport("user32", EntryPoint = "DrawEdge")]
        private static extern int DrawEdgeWin32(int hdc, ref RECT qrc, int edge, int grfFlags);

        private const int BF_RECT = 15;             // DrawEdge 函数的第四个参数
        private const int EDGE_RAISED = 5;          // DrawEdge 函数的第三个参数
        private readonly Callback mCallback;        // 回调
        private bool mHasBorder;                    // 有边框则为 true，否则为 false
        private readonly Bitmap mImage;             // 图片
        private readonly Point mOriginalPosition;   // 原位置，即刚被创建时的初始位置

        /**
         * 构造方法。
         * @param callback  回调
         * @param hasBorder 有边框则为 TRUE，否则为 FALSE
         * @param image     图片
         * @param parent    父窗口
         * @param rect      位置、尺寸
         */
        public PictureCtrl(Callback callback, bool hasBorder, Image image, Control parent, Rectangle rect) {
            // 初始化控件
            this.InitializeComponent();

            // 初始化成员
            mCallback = callback;
            mHasBorder = hasBorder;
            mImage = new Bitmap(rect.Width, rect.Height);
            Bounds = rect;
            Graphics.FromImage(mImage).DrawImage(image, new Rectangle(0, 0, rect.Width, rect.Height), Bounds, GraphicsUnit.Pixel);
            mOriginalPosition = new Point(rect.Left, rect.Top);

            // 添加到父窗口上
            parent.Controls.Add(this);
        }

        /**
         * 判断自身是否在初始位置。
         */
        public bool IsOnOriginalPosition {
            get {
                return Left == mOriginalPosition.X && Top == mOriginalPosition.Y;
            }
        }

        /**
         * 单击事件的响应方法。
         * @param sender    事件发送者
         * @param e         事件相关信息
         */
        private void OnClick(object sender, EventArgs e) {
            mCallback.MovePicture(this);
        }

        /**
         * 重绘事件的响应方法。
         * @param e 事件相关信息
         */
        protected override void OnPaint(PaintEventArgs e) {
            e.Graphics.DrawImage(mImage, 0, 0);
            if (mHasBorder) {
                int hdc = e.Graphics.GetHdc().ToInt32();
                RECT rect = new RECT(0, 0, Width, Height);
                DrawEdgeWin32(hdc, ref rect, EDGE_RAISED, BF_RECT);
                e.Graphics.ReleaseHdc();
            }
        }

        /**
         * 设置边框。
         * @param hasBorder 有边框则为 true，否则为 false
         */
        public void SetBorder(bool hasBorder) {
            if (mHasBorder == hasBorder) {
                return;
            }
            mHasBorder = hasBorder;
            base.Invalidate();
        }
    }
}
